package com.flyduck.common.interceptor;

import cn.hutool.core.util.ObjectUtil;
import com.flyduck.common.config.FlyduckConfig;
import com.flyduck.common.exception.CommonExceptionCode;
import com.flyduck.common.util.RedisUtil;
import com.flyduck.common.util.ServletUtil;
import com.flyduck.common.util.StringUtil;
import com.flyduck.common.util.TokenUtil;
import com.flyduck.common.vo.Result;
import com.flyduck.common.annotation.IgnoreAuth;
import com.flyduck.common.vo.LoginInfoVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.PatternMatchUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @program: flyduck-platform
 * @description:
 * @author: flyduck
 * @create: 2021-02-06 21:46
 **/
@Slf4j
@RequiredArgsConstructor
public class TokenInterceptor extends HandlerInterceptorAdapter {

    private final FlyduckConfig flyDuckConfig;

    private final RedisUtil redisUtil;

    private final TokenUtil tokenUtil;



    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.debug("*************************token拦截器拦截*************************");
        String requestMappingUrl = ServletUtil.getRequestMappingUrl(request);
        log.debug("请求路径为:{}",requestMappingUrl);

        List<String> whiteList = flyDuckConfig.getSecurity().getWhiteList();
        if(PatternMatchUtils.simpleMatch(whiteList.toArray(new String[0]),requestMappingUrl)){
            log.debug("*************************白名单放行*************************");
            return true;
        }
        String token = request.getHeader(flyDuckConfig.getToken().getHeader());
        if(StringUtil.isBlank(token)){
            Result result = Result.failure(CommonExceptionCode.NOT_LOGIN.getCode(),CommonExceptionCode.NOT_LOGIN.getMessage());
            ServletUtil.renderObj(response,result);
            log.debug("*************************请求头未传入token,认证失败*************************");
            return false;
        }
        log.debug("请求token为:{}",token);
        Object userInfo = redisUtil.getCacheObject(token);
        if(ObjectUtil.isNull(userInfo)){
            Result result = Result.failure(CommonExceptionCode.NOT_LOGIN.getCode(),CommonExceptionCode.NOT_LOGIN.getMessage());
            ServletUtil.renderObj(response,result);
            log.debug("*************************redis未找到此token，认证失败*************************");
            return false;
        }
        IgnoreAuth ignoreAuthAnnotation = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
        if(ObjectUtil.isNotNull(ignoreAuthAnnotation)){
            log.debug("*************************此接口不需要授权访问，直接通行*************************");
            return true;
        }
        //=====1.获取请求路径
        LoginInfoVO loginInfo = tokenUtil.getLoginInfo();
        //=====2.如果是admin用户就放行
        if ("2".equals(loginInfo.getUserInfo().getUserType())) {
            List<String> urls = loginInfo.getUrls();
            if (!PatternMatchUtils.simpleMatch(urls.toArray(new String[0]),requestMappingUrl)) {
                Result result = Result.failure(CommonExceptionCode.NOT_POWER.getCode(),CommonExceptionCode.NOT_POWER.getMessage());
                ServletUtil.renderObj(response,result);
                log.debug("*************************授权失败*************************");
                return false;
            }
        }
        log.debug("*************************认证成功,通行*************************");
        return true;
    }





}
